import { MarkerType } from '@vue-flow/core'
/**
 * 解析代码字符串并返回多个流程图的数组
 * @param {string} code - 输入的代码字符串
 * @returns {Array} - 包含多个流程图的对象数组，每个流程图包含节点和边
 */
function parseCodeToFlow(code) {
    // 检查 code 是否为字符串
    if (typeof code !== 'string') {
      throw new TypeError('The "code" parameter must be a string.');
    }
  
    // 初始化多个流程图的数组
    const flowCharts = [];
    let currentFlowChart = { nodes: [], edges: [] }; // 当前正在解析的流程图
    let currentNodeId = 1;
    let stack = []; // 用于管理嵌套结构的栈
    let switchStack = []; // 用于管理 switch 语句的嵌套结构
    let matchStack = []; // 用于管理 match 语句的嵌套结构
    let labels = {}; // 用于存储标签及其对应的节点 ID
    let currentComment = ''; // 用于存储当前的注释
    let doWhileStartNode = null; // 用于记录 do...while 循环的起始节点
    let blockStack = []; // 用于管理块的嵌套结构
  
    // 正则表达式用于处理 Markdown 格式
    const boldItalicRegex = /\*\*\*(.*?)\*\*\*/g;
    const boldRegex = /\*\*(.*?)\*\*/g;
    const italicRegex = /\*(.*?)\*/g;
    const monospaceRegex = /`(.*?)`/g;
  
    // 正则表达式用于提取自定义标签
    const customLabelRegex = /\s*$(.*?)$\s*$/;
  
    // 正则表达式用于提取块名
    const blockNameRegex = /block\s+"(.*?)"\s*\{/;
  
    function formatText(text) {
      let formattedText = text.replace(boldItalicRegex, '<b><i>$1</i></b>');
      formattedText = formattedText.replace(boldRegex, '<b>$1</b>');
      formattedText = formattedText.replace(italicRegex, '<i>$1</i>');
      formattedText = formattedText.replace(monospaceRegex, '<code>$1</code>');
      return formattedText;
    }
  
    function addComment(comment) {
      if (comment.trim()) {
        return formatText(comment.trim());
      }
      return '';
    }
  
    function createNode(label, type = 'statement', position, comment = '') {
      const newNode = {
        id: currentNodeId.toString(),
        type,
        data: { 
          label: formatText(label),
          comment: addComment(comment)
        },
        position: position || { x: 100 + (currentNodeId * 100), y: 50 + (currentNodeId * 50) },
        class: 'light',
      };
      currentFlowChart.nodes.push(newNode);
      return newNode;
    }
  
    function createEdge(source, target, label = '', withArrow = false, animated = false) {
        const newEdge = {
            id: `e${source}-${target}`,
            source: source.toString(),
            target: target.toString(),
            animated: animated,
            label: label ? formatText(label) : undefined, // 添加自定义标签
            ...(withArrow && { markerEnd: MarkerType.ArrowClosed }), // 条件性添加箭头标记
        };
        currentFlowChart.edges.push(newEdge);
    }
  
    function handleReturn(line, index) {
      // 如果 return 带有表达式
      const match = line.match(/return\s+(.*?);/);
      let returnLabel = 'return';
      if (match) {
        returnLabel = `return ${match[1]}`;
      }
  
      // 创建终止节点
      const returnNode = createNode(returnLabel, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) });
  
      // 如果有前一个节点，创建边连接到终止节点
      if (currentNodeId > 1) {
        createEdge((currentNodeId - 1).toString(), currentNodeId.toString());
      }
  
      // 将当前流程图添加到 flowCharts 中
      flowCharts.push(currentFlowChart);
  
      // 开始新的流程图
      currentFlowChart = { nodes: [], edges: [] };
      currentNodeId = 1;
      stack = [];
      switchStack = [];
      matchStack = [];
      labels = {};
      currentComment = '';
    }
  
    function handleSwitchOrMatch(line, index, isSwitch) {
      // 提取 switch 或 match 的条件
      const condition = line.match(/\b(switch|match)\s*$(.*?)$/)[2];
      const switchNode = createNode(`${isSwitch ? 'switch' : 'match'} (${condition})`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 记录当前 switch 或 match 节点的 ID
      (isSwitch ? switchStack : matchStack).push(currentNodeId);
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return switchNode;
    }
  
    function handleCaseOrBranch(line, index, isSwitch) {
      // 提取 case 或 branch 的值
      const match = line.match(/^\s*(\S+)\s*=>/);
      if (!match) return;
  
      const value = match[1];
      const caseNode = createNode(`${value} =>`, 'control', { x: 150 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 连接 switch 或 match 节点到 case 或 branch 节点
      const parentNodeId = (isSwitch ? switchStack : matchStack).pop();
      if (parentNodeId) {
        createEdge(parentNodeId.toString(), currentNodeId.toString());
        (isSwitch ? switchStack : matchStack).push(parentNodeId); // 重新压入栈中
      }
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return caseNode;
    }
  
    function handleDefaultOrCatchAll(line, index, isSwitch) {
      // 处理 default 或 _ 分支
      const defaultNode = createNode(`default`, 'control', { x: 150 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 连接 switch 或 match 节点到 default 或 _ 分支节点
      const parentNodeId = (isSwitch ? switchStack : matchStack).pop();
      if (parentNodeId) {
        createEdge(parentNodeId.toString(), currentNodeId.toString());
        (isSwitch ? switchStack : matchStack).push(parentNodeId); // 重新压入栈中
      }
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return defaultNode;
    }
  
    function handleLabel(line, index) {
      // 提取标签名称
      const match = line.match(/^(.*?):$/);
      if (!match) return;
  
      const labelName = match[1].trim();
      const labelNode = createNode(labelName, 'label', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 存储标签及其对应的节点 ID
      labels[labelName] = currentNodeId;
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return labelNode;
    }
  
    function handleGotoOrLoop(line, index) {
      // 提取目标标签名称
      const match = line.match(/(goto|loop)\s+(\S+);/);
      if (!match) return;
  
      const [_, keyword, targetLabel] = match;
      const gotoNode = createNode(`${keyword} ${targetLabel}`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 查找目标标签节点 ID
      const targetNodeId = labels[targetLabel];
      if (targetNodeId) {
        // 创建从当前节点到目标标签节点的跳转边
        createEdge(currentNodeId.toString(), targetNodeId.toString());
      } else {
        console.warn(`Label "${targetLabel}" not found.`);
      }
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return gotoNode;
    }
  
    function handleNop(line, index) {
      // 创建一个小的中间节点
      const nopNode = createNode('nop', 'nop', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 如果有前一个节点，创建边连接到 nop 节点
      if (currentNodeId > 1) {
        createEdge((currentNodeId - 1).toString(), currentNodeId.toString());
      }
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return nopNode;
    }
  
    function handleDoWhileStart(line, index) {
      // 创建 do 节点
      const doNode = createNode('do', 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 记录 do 节点的 ID
      doWhileStartNode = currentNodeId;
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return doNode;
    }
  
    function handleDoWhileEnd(line, index) {
      // 提取 while 的条件
      const match = line.match(/while\s*$(.*?)$\s*;/);
      if (!match) return;
  
      const condition = match[1];
      const whileNode = createNode(`while (${condition})`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 创建从 while 节点回到 do 节点的边
      if (doWhileStartNode) {
        createEdge(currentNodeId.toString(), doWhileStartNode.toString());
      } else {
        console.warn('No matching "do" statement found for "while".');
      }
  
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return whileNode;
    }
  
    function handleIfElse(line, index) {
        // 提取条件
        const conditionMatch = line.match(/if\s*\((.*?)\)/);
        const elseMatch = line.startsWith('else');
        if (conditionMatch) {
            const condition = conditionMatch[1];
            const conditionNode = createNode(`${condition}`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
    
            // 创建边，连接前一个节点到条件节点，并设置 label 为 true
            if (currentNodeId > 1) {
                createEdge((currentNodeId - 1).toString(), currentNodeId.toString(), '', true, false, true);
            }
    
            stack.push(currentNodeId);
            currentNodeId++;
            currentComment = ''; // 清空当前注释
    
            return conditionNode;
        } else if (elseMatch) {
            const elseNode = createNode('else', 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
    
            // 创建边，连接前一个节点到 else 节点，并设置 label 为 false
            if (currentNodeId > 1) {
                createEdge((currentNodeId - 1).toString(), currentNodeId.toString(), '', true, false, false);
            }
    
            stack.push(currentNodeId);
            currentNodeId++;
            currentComment = ''; // 清空当前注释
    
            return elseNode;
        }
    }
  
    function handleWhile(line, index) {
      // 提取 while 的条件
      const match = line.match(/while\s*$(.*?)$\s*;/);
      if (!match) return;
  
      const condition = match[1];
      const whileNode = createNode(`while (${condition})`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 检查是否有自定义标签
      const labelMatch = line.match(customLabelRegex);
      const label = labelMatch ? labelMatch[1] : '';
  
      // 创建边，连接前一个节点到 while 节点
      if (currentNodeId > 1) {
        createEdge((currentNodeId - 1).toString(), currentNodeId.toString(), label);
      }
  
      stack.push(currentNodeId);
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return whileNode;
    }
  
    function handleFor(line, index) {
      // 提取 for 的条件
      const match = line.match(/for\s*$(.*?)$\s*;/);
      if (!match) return;
  
      const condition = match[1];
      const forNode = createNode(`for (${condition})`, 'control', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
  
      // 检查是否有自定义标签
      const labelMatch = line.match(customLabelRegex);
      const label = labelMatch ? labelMatch[1] : '';
  
      // 创建边，连接前一个节点到 for 节点
      if (currentNodeId > 1) {
        createEdge((currentNodeId - 1).toString(), currentNodeId.toString(), label);
      }
  
      stack.push(currentNodeId);
      currentNodeId++;
      currentComment = ''; // 清空当前注释
  
      return forNode;
    }
  
    function handleExpression(line, index) {
        // 提取表达式
        const expression = line.slice(0, -1); // 去掉末尾的分号
    
        // 检查是否有自定义标签
        const labelMatch = line.match(customLabelRegex);
        const label = labelMatch ? labelMatch[1] : '';
    
        // 获取上一个节点的位置
        let position = { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) };
        if (currentNodeId > 1) {
            const previousNode = currentFlowChart.nodes[currentNodeId - 2]; // 上一个节点的索引是 currentNodeId - 2
            position = { x: previousNode.position.x, y: previousNode.position.y + 70 }; // 设置在上一个节点的正下方
        }
    
        // 创建表达式节点
        const expressionNode = createNode(expression, 'statement', position, currentComment);
    
        // 创建边，连接前一个节点到表达式节点
        if (currentNodeId > 1) {
            createEdge((currentNodeId - 1).toString(), currentNodeId.toString(), label, true);
        }
    
        currentNodeId++;
        currentComment = ''; // 清空当前注释
    
        return expressionNode;
    }
  
    function handleBlockStart(line, index) {
      // 检查是否有块名
      const blockNameMatch = line.match(blockNameRegex);
      let blockName = '';
  
      if (blockNameMatch) {
        blockName = blockNameMatch[1];
        // 创建命名块节点
        const blockNode = createNode(`Block: ${blockName}`, 'block', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
        currentNodeId++;
      } else {
        // 创建匿名块节点
        const blockNode = createNode('Block', 'block', { x: 100 + (currentNodeId * 100), y: 50 + (index * 50) }, currentComment);
        currentNodeId++;
      }
  
      // 将当前块信息压入栈中
      blockStack.push({ id: currentNodeId - 1, name: blockName });
      currentComment = ''; // 清空当前注释
    }
  
    function handleBlockEnd(line, index) {
      // 弹出当前块信息
      const blockInfo = blockStack.pop();
      if (!blockInfo) {
        console.warn('No matching "block" start found for "}".');
        return;
      }
  
      // 创建边，连接最后一个节点到块结束节点
      if (currentNodeId > 1) {
        createEdge((currentNodeId - 1).toString(), blockInfo.id.toString());
      }
  
      currentComment = ''; // 清空当前注释
    }
  
    const lines = code.split('\n');
    
    lines.forEach((line, index) => {
      // 去除行首尾的空白字符
      const trimmedLine = line.trim();
  
      // 忽略空行
      if (!trimmedLine) {
        return;
      }
  
      // 处理单行注释
      if (trimmedLine.startsWith('//')) {
        currentComment += ' ' + trimmedLine.slice(2).trim();
        return;
      }
  
      // 处理多行注释开始
      if (trimmedLine.startsWith('/*')) {
        currentComment += ' ' + trimmedLine.slice(2).trim();
        return;
      }
  
      // 处理多行注释中间部分
      if (trimmedLine.includes('/*') && trimmedLine.includes('*/')) {
        currentComment += ' ' + trimmedLine.slice(trimmedLine.indexOf('/*') + 2, trimmedLine.indexOf('*/')).trim();
        currentComment = addComment(currentComment);
        return;
      }
  
      // 处理多行注释结束
      if (trimmedLine.endsWith('*/')) {
        currentComment += ' ' + trimmedLine.slice(0, trimmedLine.indexOf('*/')).trim();
        currentComment = addComment(currentComment);
        return;
      }
  
      // 处理不可见注释
      if (trimmedLine.startsWith('#')) {
        return;
      }
  
      // 处理 return 语句
      if (trimmedLine.startsWith('return')) {
        handleReturn(line, index);
        return;
      }
  
      // 处理 switch 语句
      if (trimmedLine.startsWith('switch(')) {
        handleSwitchOrMatch(line, index, true);
        return;
      }
  
      // 处理 match 语句
      if (trimmedLine.startsWith('match')) {
        handleSwitchOrMatch(line, index, false);
        return;
      }
  
      // 处理 case 或 branch 语句
      if (trimmedLine.includes('=>')) {
        handleCaseOrBranch(line, index, trimmedLine.startsWith('switch') || switchStack.length > 0);
        return;
      }
  
      // 处理 default 或 _ 分支
      if (trimmedLine.startsWith('default') || trimmedLine.startsWith('_')) {
        handleDefaultOrCatchAll(line, index, trimmedLine.startsWith('switch') || switchStack.length > 0);
        return;
      }
  
      // 处理标签声明
      if (trimmedLine.endsWith(':')) {
        handleLabel(line, index);
        return;
      }
  
      // 处理 goto 或 loop 语句
      if (trimmedLine.startsWith('goto') || trimmedLine.startsWith('loop')) {
        handleGotoOrLoop(line, index);
        return;
      }
  
      // 处理 nop 命令
      if (trimmedLine === 'nop;') {
        handleNop(line, index);
        return;
      }
  
      // 处理 if 和 else 语句
      if (trimmedLine.startsWith('if') || trimmedLine.startsWith('else')) {
        handleIfElse(line, index);
        return;
      }
  
      // 处理 while 语句
      if (trimmedLine.startsWith('while')) {
        handleWhile(line, index);
        return;
      }
  
      // 处理 for 语句
      if (trimmedLine.startsWith('for')) {
        handleFor(line, index);
        return;
      }
  
      // 处理 do...while 语句
      if (trimmedLine.startsWith('do')) {
        handleDoWhileStart(line, index);
        return;
      }
  
      // 处理 while 结束 do...while 语句
      if (trimmedLine.startsWith('while') && doWhileStartNode) {
        handleDoWhileEnd(line, index);
        doWhileStartNode = null; // 重置 doWhileStartNode
        return;
      }
  
      // 处理普通表达式
      if (trimmedLine.endsWith(';')) {
        handleExpression(line, index);
        return;
      }
  
      // 处理块的开始
      if (trimmedLine.startsWith('block {') || trimmedLine.startsWith('block "')) {
        handleBlockStart(line, index);
        return;
      }
  
      // 处理块的结束
      if (trimmedLine === '}') {
        handleBlockEnd(line, index);
        return;
      }
  
      // 处理结束块
      if (trimmedLine === '}') {
        const lastNodeId = stack.pop();
        // 连接最后一个节点到当前节点
        if (currentNodeId > 1) {
          createEdge(lastNodeId.toString(), (currentNodeId - 1).toString());
        }
        return;
      }
    });
  
    // 如果最后一个流程图没有被添加，添加它
    if (currentFlowChart.nodes.length > 0) {
      flowCharts.push(currentFlowChart);
    }
    if (flowCharts.length === 0) {
        return [{
            nodes: [],
            edges: []
        }];
    }
    // 返回多个流程图的数组
    return flowCharts;
  }
  
  // 导出解析函数
  export { parseCodeToFlow };